package com.managedBean.merchant;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

import org.apache.commons.io.FilenameUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;

import com.controller.merchant.OrganizeMenuController;
import com.controller.merchant.ProductController;
import com.dto.merchant.ChildCatalogDTO;
import com.dto.merchant.Level1DTO;
import com.dto.merchant.Level2DTO;
import com.dto.merchant.Level3DTO;
import com.dto.merchant.MasterCatalogDTO;

//commons-io-1.4 and commons-fileuplaod-1.2.1.jar
@ManagedBean(name = "addProduct")
@ViewScoped
public class AddProductManagedBean implements Serializable {

	private static final long serialVersionUID = -446442459845576466L;
	private StreamedContent image;
	private String itemSize;
	private double itemPrice;
	private double itemSrp;
	private byte[] bFile;
	UploadedFile file;
	File result;
	String path;
	String uploadPath;
	private List<MasterCatalogDTO> masterlist;
	private List<ChildCatalogDTO> itemsList;
	private int masterTableId;
	private int l1Id;
	private int l2Id;
	private int l3Id;
	private List<Level1DTO> l1List;
	private List<Level2DTO> l2List;
	private List<Level3DTO> l3List;
	private List<MasterCatalogDTO> filterdMasterlist;
	@ManagedProperty(value = "#{productController}")
	private ProductController productController;
	@ManagedProperty(value = "#{organizeMenuController}")
	private OrganizeMenuController organizeMenuController;
	public AddProductManagedBean() {
		super();
	}

	@PostConstruct
	public void init() {
		masterlist = new ArrayList<MasterCatalogDTO>();
		filterdMasterlist=new ArrayList<MasterCatalogDTO>();
		masterlist = productController.findAllMasters();
		filterdMasterlist.addAll(masterlist);
		itemsList = productController.findAllItems();
		l1List = new ArrayList<Level1DTO>();
		try {
			l1List = organizeMenuController.findAll();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// TODO decide whether to store the image in database or store it in other
	// server/context path and store the url in db
	// get suggestions and recommendations from friends and do this part
	public void handleFileUpload(FileUploadEvent event) {
		bFile = event.getFile().getContents();
		uploadToContext(event);
	}

	

	public void uploadToContext(FileUploadEvent event) {
		ExternalContext extContext = FacesContext.getCurrentInstance()
				.getExternalContext();
		path = extContext.getRealPath("/");
		file = event.getFile();
		String fileName = FilenameUtils.getBaseName(file.getFileName()) + "."
				+ FilenameUtils.getExtension(file.getFileName());
		result = new File(path + "images" + File.separator + "upload"
				+ File.separator + fileName);
		System.out.println(path + "images" + File.separator + "upload"
				+ File.separator + fileName);
		uploadPath = "/images/upload/" + fileName;
	}

	public void uploadFile() {
		if(null!=result){
		try {
			FileOutputStream fileOutputStream = new FileOutputStream(result);
			byte[] buffer = new byte[40000];
			int bulk;
			InputStream inputStream = file.getInputstream();
			while (true) {
				bulk = inputStream.read(buffer);
				if (bulk < 0) {
					break;
				}
				fileOutputStream.write(buffer, 0, bulk);
				fileOutputStream.flush();
			}
			fileOutputStream.close();
			inputStream.close();
//			FacesMessage msg = new FacesMessage("File Description",
//					"file name: " + file.getFileName() + " File size: "
//							+ file.getSize() / 1024 + " Kb Content type: "
//							+ file.getContentType() + " the file was uploaded.");
		} catch (IOException e) {
			e.printStackTrace();
			FacesMessage error = new FacesMessage(FacesMessage.SEVERITY_ERROR,
					" the files were not uploaded!", "");
			FacesContext.getCurrentInstance().addMessage(null, error);
		}
		}
	}

	public void addProduct() {
		ChildCatalogDTO dto = new ChildCatalogDTO();
		dto.setChildItemImagePath(uploadPath);
		dto.setChildItemPrice(new BigDecimal(itemPrice));
		dto.setChildItemSize(itemSize);
		dto.setChildItemSrp(new BigDecimal(itemSrp));
		dto.setChildItemImage(bFile);
		dto.setMasterTableId(masterTableId);
		try {
			productController.addItem(dto);
			uploadFile();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		FacesMessage msg = new FacesMessage("Item Added Successfully");
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	public void l1Selected(){
		for(Level1DTO level1dto:l1List){
			if(level1dto.getL1Id()==l1Id){
				l2List=level1dto.getLevel2Tables();
				break;
			}
		}
		filterdMasterlist.clear();
		for(MasterCatalogDTO dto:masterlist){
			if(dto.getL1Id()==l1Id){
				filterdMasterlist.add(dto);
			}
		}
	}
	
	public void l2Selected(){
		for(Level2DTO level2dto:l2List){
			if(level2dto.getL2Id()==l2Id){
				l3List=level2dto.getLevel3Tables();
				break;
			}
		}
		filterdMasterlist.clear();
		for(MasterCatalogDTO dto:masterlist){
			if(dto.getL2Id()==l2Id){
				filterdMasterlist.add(dto);
			}
		}
	}
	
	public void l3Selected(){
		filterdMasterlist.clear();
		for(MasterCatalogDTO dto:masterlist){
			if(dto.getL3Id()==l3Id){
				filterdMasterlist.add(dto);
			}
		}
	}
	/**
	 * @return the image
	 */
	public StreamedContent getImage() {
		return image;
	}

	/**
	 * @param image
	 *            the image to set
	 */
	public void setImage(StreamedContent image) {
		this.image = image;
	}

	/**
	 * @return the itemSize
	 */
	public String getItemSize() {
		return itemSize;
	}

	/**
	 * @param itemSize
	 *            the itemSize to set
	 */
	public void setItemSize(String itemSize) {
		this.itemSize = itemSize;
	}

	/**
	 * @return the itemPrice
	 */
	public double getItemPrice() {
		return itemPrice;
	}

	/**
	 * @param itemPrice
	 *            the itemPrice to set
	 */
	public void setItemPrice(double itemPrice) {
		this.itemPrice = itemPrice;
	}

	/**
	 * @return the itemSrp
	 */
	public double getItemSrp() {
		return itemSrp;
	}

	/**
	 * @param itemSrp
	 *            the itemSrp to set
	 */
	public void setItemSrp(double itemSrp) {
		this.itemSrp = itemSrp;
	}

	
	/**
	 * @return the masterlist
	 */
	public List<MasterCatalogDTO> getMasterlist() {
		return masterlist;
	}

	/**
	 * @param masterlist the masterlist to set
	 */
	public void setMasterlist(List<MasterCatalogDTO> masterlist) {
		this.masterlist = masterlist;
	}

	/**
	 * @return the masterTableId
	 */
	public int getMasterTableId() {
		return masterTableId;
	}

	/**
	 * @param masterTableId
	 *            the masterTableId to set
	 */
	public void setMasterTableId(int masterTableId) {
		this.masterTableId = masterTableId;
	}

	/**
	 * @return the productController
	 */
	public ProductController getProductController() {
		return productController;
	}

	/**
	 * @param productController the productController to set
	 */
	public void setProductController(ProductController productController) {
		this.productController = productController;
	}

	/**
	 * @return the itemsList
	 */
	public List<ChildCatalogDTO> getItemsList() {
		return itemsList;
	}

	/**
	 * @param itemsList the itemsList to set
	 */
	public void setItemsList(List<ChildCatalogDTO> itemsList) {
		this.itemsList = itemsList;
	}

	/**
	 * @return the l1Id
	 */
	public int getL1Id() {
		return l1Id;
	}

	/**
	 * @param l1Id the l1Id to set
	 */
	public void setL1Id(int l1Id) {
		this.l1Id = l1Id;
	}

	/**
	 * @return the l2Id
	 */
	public int getL2Id() {
		return l2Id;
	}

	/**
	 * @param l2Id the l2Id to set
	 */
	public void setL2Id(int l2Id) {
		this.l2Id = l2Id;
	}

	/**
	 * @return the l3Id
	 */
	public int getL3Id() {
		return l3Id;
	}

	/**
	 * @param l3Id the l3Id to set
	 */
	public void setL3Id(int l3Id) {
		this.l3Id = l3Id;
	}

	/**
	 * @return the l1List
	 */
	public List<Level1DTO> getL1List() {
		return l1List;
	}

	/**
	 * @param l1List the l1List to set
	 */
	public void setL1List(List<Level1DTO> l1List) {
		this.l1List = l1List;
	}

	/**
	 * @return the l2List
	 */
	public List<Level2DTO> getL2List() {
		return l2List;
	}

	/**
	 * @param l2List the l2List to set
	 */
	public void setL2List(List<Level2DTO> l2List) {
		this.l2List = l2List;
	}

	/**
	 * @return the l3List
	 */
	public List<Level3DTO> getL3List() {
		return l3List;
	}

	/**
	 * @param l3List the l3List to set
	 */
	public void setL3List(List<Level3DTO> l3List) {
		this.l3List = l3List;
	}

	/**
	 * @return the organizeMenuController
	 */
	public OrganizeMenuController getOrganizeMenuController() {
		return organizeMenuController;
	}

	/**
	 * @param organizeMenuController the organizeMenuController to set
	 */
	public void setOrganizeMenuController(
			OrganizeMenuController organizeMenuController) {
		this.organizeMenuController = organizeMenuController;
	}

	/**
	 * @return the filterdMasterlist
	 */
	public List<MasterCatalogDTO> getFilterdMasterlist() {
		return filterdMasterlist;
	}

	/**
	 * @param filterdMasterlist the filterdMasterlist to set
	 */
	public void setFilterdMasterlist(List<MasterCatalogDTO> filterdMasterlist) {
		this.filterdMasterlist = filterdMasterlist;
	}

}
